package com.guodi.model.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.guodi.common.constant.StatusCode;
import com.guodi.common.utils.AjaxResult;
import com.guodi.common.utils.UuidUtil;
import com.guodi.core.boot.ctrl.BaseController;
import com.guodi.model.entity.IdtIndicators;
import com.guodi.model.entity.IdtYearRelevance;
import com.guodi.model.service.IIdtIndicatorsService;
import com.guodi.model.service.IIdtWarnRuleService;
import com.guodi.model.service.IIdtYearRelevanceService;
import com.guodi.model.utils.ExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @描述：指标年份关联表控制类
 * @作者: 彭辉
 * @日期: 2020-06-05
 */
@RestController
@RequestMapping("/IdtYearRelevance")
@Api(value = "API - IdtYearRelevanceController", description = "指标年份关联表")
public class IdtYearRelevanceController extends BaseController {

    @Resource
    public IIdtYearRelevanceService idtYearRelevanceService;

    @Resource
    public IIdtIndicatorsService iIdtIndicatorsService;

    @Resource
    public IIdtWarnRuleService idtWarnRuleService;
    /**
    * @描述: 根据实体属性分页查询
    * @入参:
    * @出参:
    * @作者: 彭辉
    * @日期: 2020-06-05
    **/
    @PostMapping("/listByKeyWordPaging")
    @ApiOperation(value = "根据关键字分页查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "keyWord", value = "查询的关键字",dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码，从1开始",dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小",dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "orderField", value = "排序的字段",dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orderType", value = "排序的方式，传入asc表示升序，传入desc 降序排序",dataType = "string", paramType = "query"),
    })
    public AjaxResult listByKeyWordPaging(String keyWord, Integer page, Integer pageSize, String orderField, String orderType){
        HashMap map = new HashMap();
        if(page == null){
            page =1;
        }
        if(pageSize == null){
            pageSize = 10;
        }
        Integer start = (page-1)*pageSize;
        List<IdtYearRelevance> idtYearRelevanceList =idtYearRelevanceService.listByKeyWord(keyWord,pageSize,start,orderField,orderType);
        Integer selectCount = idtYearRelevanceService.listByKeyWordCount(keyWord);
        map.put("result",idtYearRelevanceList);
        map.put("total",selectCount);
        map.put("page",page);
        map.put("pageSize",pageSize);
        return new AjaxResult(map);
    }

    /**
     * @描述: 根据主键查询
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/findById")
    @ApiOperation(value = "根据主键查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult findById(String id) {
        if(StringUtils.isBlank(id)){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"id不能为空");
        }
        IdtYearRelevance idtYearRelevance = idtYearRelevanceService.getById(id);
        return new AjaxResult(idtYearRelevance);
    }

    /**
     * @描述: 新增
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/save")
    @ApiOperation(value = "新增")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "indicatorsId", value = "指标id", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "monitorReportYear", value = "监测/上报年份", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "planTargetYear", value = "规划目标年份", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "warnRuleId", value = "预警规则id", required = true, dataType = "string", paramType = "query"),
    })
    public AjaxResult save(IdtYearRelevance idtYearRelevance){
        if(StringUtils.isBlank(idtYearRelevance.getIndicatorsId())){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"指标id不能为空");
        }
        if(StringUtils.isBlank(idtYearRelevance.getMonitorReportYear())){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"监测/上报年份不能为空");
        }
        if(idtYearRelevance.getPlanTargetYear()== null){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"规划目标年份不能为空");
        }
        String[] paramScope = idtYearRelevance.getMonitorReportYear().split("-");
        int paramYearStart = Integer.parseInt(paramScope[0]);
        int paramYearEnd = Integer.parseInt(paramScope[1]);
        if(paramYearStart >= paramYearEnd){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"输入的监测/上报年份范围不对");
        }
        //相同指标id的要判断监测年份是否有先交错重叠
        LambdaQueryWrapper<IdtYearRelevance> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(IdtYearRelevance::getIndicatorsId,idtYearRelevance.getIndicatorsId());
        List<IdtYearRelevance> idtYearRelevanceList = idtYearRelevanceService.list(queryWrapper);
        if(judgeScope(idtYearRelevanceList,paramYearStart,paramYearEnd)){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"该指标项监测值/上报值年份已存在");
        }
        idtYearRelevance.setId(UuidUtil.get32UUID());
        prepareData(idtYearRelevance, true);
        idtYearRelevanceService.save(idtYearRelevance);
        return new AjaxResult(idtYearRelevance);
    }

    /**
     * @描述: 修改
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020-06-05
     **/
    @PostMapping("/update")
    @ApiOperation(value = "修改")
    public AjaxResult update(IdtYearRelevance idtYearRelevance) {
        //获取原来的记录
        IdtYearRelevance sourceIdtYearRelevance = idtYearRelevanceService.getById(idtYearRelevance.getId());
        if(!idtYearRelevance.getMonitorReportYear().equals(sourceIdtYearRelevance.getMonitorReportYear()) || !idtYearRelevance.getIndicatorsId().equals(sourceIdtYearRelevance.getIndicatorsId())){
            String[] paramScope = idtYearRelevance.getMonitorReportYear().split("-");
            int paramYearStart = Integer.parseInt(paramScope[0]);
            int paramYearEnd = Integer.parseInt(paramScope[1]);
            if(paramYearStart >= paramYearEnd){
                return new AjaxResult(StatusCode.ERROR_CODE_40005,"输入的监测/上报年份范围不对");
            }
            //要判断修改的不能在已有的年份范围内的
            //相同指标id的要判断监测年份是否有先交错重叠
            LambdaQueryWrapper<IdtYearRelevance> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(IdtYearRelevance::getIndicatorsId,idtYearRelevance.getIndicatorsId());
            queryWrapper.ne(IdtYearRelevance::getId,idtYearRelevance.getId());
            List<IdtYearRelevance> idtYearRelevanceList = idtYearRelevanceService.list(queryWrapper);
            if(judgeScope(idtYearRelevanceList,paramYearStart,paramYearEnd)){
                return new AjaxResult(StatusCode.ERROR_CODE_40005,"该指标项监测值/上报值年份已存在");
            }
        }
        prepareData(idtYearRelevance, false);
        idtYearRelevanceService.updateById(idtYearRelevance);
        return new AjaxResult(idtYearRelevance);
    }

    /**
     * @描述: 根据主键删除
     * @入参: id
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/delete")
    @ApiOperation(value = "根据主键删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult delete(String id){
        if(StringUtils.isBlank(id)){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"id不能为空");
        }
        idtYearRelevanceService.removeById(id);
        return new AjaxResult();
    }


    /**
     * @描述:删除多条记录
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/15 16:55
    **/
    @PostMapping("/deleteByIds")
    @ApiOperation(value = "根据多个id删除,多个id用,隔开")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult deleteByIds(String ids){
        if(StringUtils.isBlank(ids)){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"ids不能为空");
        }
        String[] idsAry = ids.split(",");
        List<String> idList = Arrays.asList(idsAry);
        idtYearRelevanceService.removeByIds(idList);
        return new AjaxResult();
    }

    /**
     * @描述:导出Excel
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/12 17:20
    **/
    @PostMapping("/exportExcel")
    @ApiOperation(value = "导出指标Excel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "exportType", value = "导出类型,传入all默认导出全部,否则根据,分隔删除", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "ids", value = "导出指标id集合", required = false, dataType = "string", paramType = "query")
    })
    public void exportExcel(String exportType, String ids) {
        List<IdtYearRelevance> list ;
        if ("all".equals(exportType)) {
            // 导出所有指标
            list = idtYearRelevanceService.listAll();
        } else {
            List<String> idsList = Arrays.asList(ids.split(","));
            // 导出选中指标
            list = idtYearRelevanceService.listAllByIds(idsList);
        }
        List<Object[]> dataList = new ArrayList<Object[]>();
        for (int i = 0; i < list.size(); i++) {
            IdtYearRelevance idtYearRelevance = list.get(i);
            Object[] datas = new Object[7];
            datas[0] = idtYearRelevance.getIdtCode();
            datas[1] = idtYearRelevance.getIdtName();
            datas[2] = idtYearRelevance.getMonitorReportYear();
            datas[3] = idtYearRelevance.getBasePeriodYear();
            datas[4] = idtYearRelevance.getPlanTargetYear();
            datas[5] = idtYearRelevance.getIdtWarnRuleName();
            datas[6] = idtYearRelevance.getExplain();
            dataList.add(datas);
        }
        // 导出Excel
        String[] titles = {"指标编号", "指标项", "监测值/上报值年份", "基期年", "规划目标年份", "预警规则","指标说明"};
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        ExcelUtil.exportExcel(response, "指标对标信息", "指标对标信息", titles, dataList);
    }

    /**
     * @描述:导入Excel
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/15 19:03
     **/
    @PostMapping("/importExcel")
    @ApiOperation(value = "导入Excel")
    public AjaxResult importExcel(MultipartFile multipartFile) {
        if (multipartFile.isEmpty()) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "导入文件不能为空！");
        }
        // 根据上传MultipartFile对象获取excel数据集
        List<List<String>> excelList = ExcelUtil.getExcelData(multipartFile);
        if (excelList == null || excelList.size() <= 1) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "导入文件数据为空！");
        }
        Pattern reportYearPattern = Pattern.compile("[0-9]{4}-[0-9]{4}");
        Pattern targetYearPattern = Pattern.compile("[0-9]{4}");
        for(int j = 1; j < excelList.size(); j++) {
            List<String> row = excelList.get(j);
            // 去空格
            for(int i = 0; i < row.size(); i++) {
                if(row.get(i) == null){
                    row.set(i,"");
                }else{
                    row.set(i,row.get(i).trim());
                }
            }
            // 去除指标编码的小数点
            int idtCodeIndex = 0;
            if (StringUtils.isBlank(row.get(idtCodeIndex))){
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "第" + (j + 1) + "行指标编码为空！");
            }
            if (row.get(idtCodeIndex).contains(".")){
                row.set(idtCodeIndex, row.get(idtCodeIndex).substring(0, row.get(idtCodeIndex).indexOf(".") ));
            }
            // 去除规划目标年份的小数点
            int targetYearIndex = 3;
            if (StringUtils.isBlank(row.get(targetYearIndex) )){
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "第" + (j + 1) + "行规划目标年份为空！");
            }
            if (row.get(targetYearIndex).contains(".")){
                row.set(targetYearIndex, row.get(targetYearIndex).substring(0, row.get(targetYearIndex).indexOf(".") ));
            }
            if (!targetYearPattern.matcher(row.get(targetYearIndex)).matches()){
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "第" + (j + 1) + "行规划目标年份（" + row.get(targetYearIndex) + "）不符合规范！");
            }
            // 上报年份
            int reportYearIndex = 2;
            if (StringUtils.isBlank(row.get(reportYearIndex) )){
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "第" + (j + 1) + "行监测值/上报值年份为空！");
            }
            if (!reportYearPattern.matcher(row.get(reportYearIndex)).matches()){
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "第" + (j + 1) + "行监测值/上报值年份（" + row.get(reportYearIndex) + "）不符合规范！");
            }
            String[] paramScope = row.get(reportYearIndex).split("-");
            int paramYearStart = Integer.parseInt(paramScope[0]);
            int paramYearEnd = Integer.parseInt(paramScope[1]);
            if(paramYearStart >= paramYearEnd){
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "第" + (j + 1) + "行监测值/上报值年份（" + row.get(reportYearIndex) + "）开始年份大于等于结束年份！");
            }
        }
        // 存储新增、更新指标集合
        List<IdtYearRelevance> saveUpdateList = new ArrayList<>();
        // 记录对标记录重复的指标名
        List<String> yearRelevanceRepeatIdtName = new LinkedList<>();
        for (int i = 1; i < excelList.size(); i++) {
            List<String> dataList = excelList.get(i);
            String idtCode = dataList.get(0);
            LambdaQueryWrapper<IdtIndicators> queryWrapper = new QueryWrapper().lambda();
            queryWrapper.eq(IdtIndicators::getCode,idtCode);
            IdtIndicators idtIndicators = iIdtIndicatorsService.getOne(queryWrapper);
            if (Objects.isNull(idtIndicators)){
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "第" + (i + 1) + "行指标不存在！");
            }
            IdtYearRelevance idtYearRelevance = new IdtYearRelevance();
            //String baseYear = dataList.get(3).indexOf(".") >=0 ? dataList.get(3).substring(0,dataList.get(3).indexOf(".")) : dataList.get(3);
            String targetYear = dataList.get(3).indexOf(".") >=0 ? dataList.get(3).substring(0,dataList.get(3).indexOf(".")) : dataList.get(3);
            idtYearRelevance.setMonitorReportYear(dataList.get(2));
            //idtYearRelevance.setBasePeriodYear(Integer.parseInt(baseYear));
            idtYearRelevance.setPlanTargetYear(Integer.parseInt(targetYear));
            if(idtIndicators != null){
                // 切割监测值/上报值年份
                String[] paramScope = dataList.get(2).split("-");
                int paramYearStart = Integer.parseInt(paramScope[0]);
                int paramYearEnd = Integer.parseInt(paramScope[1]);
                if(paramYearStart >= paramYearEnd){
                    continue;
                }
                //相同指标id的要判断监测年份是否有先交错重叠
                LambdaQueryWrapper<IdtYearRelevance> queryWrapper11 = new LambdaQueryWrapper<>();
                queryWrapper11.eq(IdtYearRelevance::getIndicatorsId,idtIndicators.getId());
                List<IdtYearRelevance> idtYearRelevanceList = idtYearRelevanceService.list(queryWrapper11);
                if(judgeScope(idtYearRelevanceList,paramYearStart,paramYearEnd)){
                    yearRelevanceRepeatIdtName.add(idtIndicators.getName() + "(" + idtCode + ")");
                    continue;
                }
                idtYearRelevance.setIndicatorsId(idtIndicators.getId());
                prepareData(idtYearRelevance,true);
                idtYearRelevance.setId(UuidUtil.get32UUID());
                idtYearRelevance.setExplain(dataList.get(4));
                saveUpdateList.add(idtYearRelevance);
            }
        }
        if (!yearRelevanceRepeatIdtName.isEmpty()){
            String msg = yearRelevanceRepeatIdtName.stream().collect(Collectors.joining("，"));
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "以下指标以存在对应年份的对标配制：" + msg);
        }
        if (saveUpdateList.size() > 0) {
            // 批量保存更新
            idtYearRelevanceService.saveOrUpdateBatch(saveUpdateList);
        }
        return new AjaxResult(saveUpdateList);
    }

    /**
     * @描述:判断指标是否在已有的范围内
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/12 15:25
    **/
    private boolean judgeScope(List<IdtYearRelevance> idtYearRelevanceList, int paramYearStart, int paramYearEnd){
        for (int i = 0; i <idtYearRelevanceList.size() ; i++) {
            String monitor_report_year = idtYearRelevanceList.get(i).getMonitorReportYear();
            String[] yearScope = monitor_report_year.split("-");
            int compareYearStart = Integer.parseInt(yearScope[0]);
            int compareYearEnd = Integer.parseInt(yearScope[1]);
            for(int j=paramYearStart;j<=paramYearEnd;j++){
                if((j >= compareYearStart && j <= compareYearEnd)){
                    return true;
                }
            }
        }
        return false;
    }


    private void prepareData(IdtYearRelevance idtYearRelevance, boolean isSave) {
        if(isSave){
            idtYearRelevance.setCreator(this.getUser().getUserId().toString());
            idtYearRelevance.setCreateTime(new Date());
            //防止误修改
            idtYearRelevance.setModifier(null);
            idtYearRelevance.setModifyTime(null);
        }else{
            idtYearRelevance.setModifier(this.getUser().getUserId().toString());
            idtYearRelevance.setModifyTime(new Date());
            //防止误修改
            idtYearRelevance.setCreator(null);
            idtYearRelevance.setCreateTime(null);
        }
    }
}
